﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Apps.Yunwei.Views;
using Apps.Yunwei.YunWeiService;
using Microsoft.Expression.Interactivity.Core;
using QDP.Platform.Services;
using QDP.Platform.Silverlight;
using QDP.Platform.Silverlight.Aware;
namespace Apps.Yunwei.ViewModels
{
    public class TopicsViewModel : ObservableObject, IRefreshAware
    {
        private Dictionary<string, string> Config;
        private AppObject selectApp;
        private ServiceObject selectService;
        private Action SaveAction;
        private NorOpSvClient Client = null;

        public TopicsViewModel()
        {
            this.Datas = new ObservableCollection<TopicItemObject>();

            this.DeleteCommand = new ActionCommand(this.OnDelete);
            this.SelectedCommand = new ActionCommand(this.OnSelected);
            this.SaveCommand = new ActionCommand(this.OnSave);

            this.AddAppCommand = new ActionCommand(this.InsertApp);
            this.AddSerCommand = new ActionCommand(this.InsertService);

            this.ExpandedAll = new ActionCommand(this.OnExpanedAll);
            this.CollpasedAll = new ActionCommand(this.OnCollpasedAll);
        }

        #region 公共属性定义
        // 可用于绑定的属性定义
        private Control editView;
        public Control EditView
        {
            get { return editView; }
            set
            {
                if (editView != value)
                {
                    editView = value;
                    this.Notify("EditView");
                }
            }
        }
        private bool treeIsBusy;
        public bool TreeIsBusy
        {
            get { return treeIsBusy; }
            set
            {
                if (treeIsBusy != value)
                {
                    treeIsBusy = value;
                    this.Notify("TreeIsBusy");
                }
            }
        }
        private bool detailIsBusy;
        public bool DetailIsBusy
        {
            get { return detailIsBusy; }
            set
            {
                if (detailIsBusy != value)
                {
                    detailIsBusy = value;
                    this.Notify("DetailIsBusy");
                }
            }
        }
        // 非可用于绑定的属性定义
        public ObservableCollection<TopicItemObject> Datas { get; set; }

        private TopicItemObject prvSelected;
        private TopicItemObject curSelected;
        public TopicItemObject SelectedItem
        {
            get { return curSelected; }
            set
            {
                if (curSelected != null)
                    prvSelected = curSelected;
                curSelected = value;
            }
        }
        #endregion //#region 公共属性定义

        #region 公共操作指令定义：Selected、Add、Edit、Delete等
        public ICommand AddAppCommand { get; private set; }
        public ICommand AddSerCommand { get; private set; }
        public ICommand SelectedCommand { get; private set; }
        public ICommand DeleteCommand { get; private set; }
        public ICommand SaveCommand { get; private set; }
        public ICommand ExpandedAll { get; private set; }
        public ICommand CollpasedAll { get; private set; }
        #endregion //#region 公共操作指令定义：Selected、Add、Edit、Delete、Refresh等

        #region 数据服务操作结果处理函数
        void Client_UpdateParameterCompleted(object sender, UpdateParameterCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
                return;
            }
            if (e.Result.IsSuccess == false)
            {
                this.ShowMessage("操作失败",e.Result.Message);
            }
        }

        void Client_InsertServiceCompleted(object sender, InsertServiceCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
                return;
            }
            if (e.Result.IsSuccess == false)
            {
                this.ShowMessage("操作失败",e.Result.Message);
            }
            else
            {
                var node = this.GetDataNode(selectService.Tags);
                if (node.Children.Any(p => p.ID == selectService.ID))
                {
                    var child = node.Children.First(p => p.ID == selectService.ID);
                    child.Caption = selectService.Caption;
                    child.ImageUrl1 = selectService.Icon1;
                    child.Background = selectService.Bgc;
                    child.Tags = selectService.Tags;
                    child.Order = selectService.Order;
                }
                else
                {
                    node.Children.Add(new TopicItemObject()
                    {
                        Caption = selectService.Caption,
                        ImageUrl1 = selectService.Icon1,
                        Background = selectService.Bgc,
                        ID = selectService.ID,
                        Tags = selectService.Tags,
                        Type = TopicItemType.Service,
                        Order = selectApp.Order,
                    });
                }
            }
            SaveAction = null;
        }

        void Client_InsertAppCompleted(object sender, InsertAppCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
                return;
            }
            if (e.Result.IsSuccess == false)
            {
                this.ShowMessage("操作失败",e.Result.Message);
            }
            else
            {
                var node = this.GetDataNode(selectApp.Tags);
                if (node.Children.Any(p => p.ID == selectApp.ID))
                {
                    var child = node.Children.First(p => p.ID == selectApp.ID);
                    child.Caption = selectApp.Caption;
                    child.ImageUrl1 = selectApp.Icon1;
                    child.Background = selectApp.Bgc;
                    child.Tags = selectApp.Tags;
                    child.Order = selectApp.Order;
                }
                else
                {
                    node.Children.Add(new TopicItemObject()
                    {
                        Caption = selectApp.Caption,
                        ImageUrl1 = selectApp.Icon1,
                        Background = selectApp.Bgc,
                        ID = selectApp.ID,
                        Tags=selectApp.Tags,
                        Type = TopicItemType.App,
                        Order = selectApp.Order,
                    });
                }
                SaveAction = null;
            }
        }

        void Client_UpdateServiceCompleted(object sender, UpdateServiceCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
                return;
            }
            if (e.Result.IsSuccess == false)
            {
                this.ShowMessage("操作失败",e.Result.Message);
            }
            else
            {
                // 更改目录结构
                if (SelectedItem.Tags != selectService.Tags)
                {
                    var item = this.SelectedItem;
                    // 删除原节点。
                    var sourceNode = this.GetDataNode(SelectedItem.Tags);
                    sourceNode.Children.Remove(item);
                    var node = this.GetDataNode(selectService.Tags);
                    node.Children.Add(item);
                    FillClearTree(this.Datas);
                    this.SelectedItem = item;
                    SelectedItem.Tags = selectService.Tags;
                }
                SelectedItem.Caption = selectService.Caption;
                SelectedItem.ImageUrl1 = selectService.Icon1;
                SelectedItem.Background = selectService.Bgc;
                SelectedItem.Order = selectService.Order;
            }
        }

        void Client_DeleteServiceCompleted(object sender, DeleteServiceCompletedEventArgs e)
        {
            DetailIsBusy = false;
            TreeIsBusy = false;
            
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
                return;
            }
            if (e.Result.IsSuccess == false)
            {
                this.ShowMessage("操作失败",e.Result.Message);
            }
            else
            {
                var node = this.GetDataNode(SelectedItem.Tags);
                if (node.Children.Any(p => p.ID == SelectedItem.ID))
                {
                    var curent = node.Children.First(p => p.ID == SelectedItem.ID);
                    node.Children.Remove(curent);
                    if (node.Children.Count == 0)
                    {
                        int index = SelectedItem.Tags.LastIndexOf('\\');
                        string tags = SelectedItem.Tags.Substring(0, index);
                        string caption = SelectedItem.Tags.Substring(index);
                        var parentNode = this.GetDataNode(tags);
                        parentNode.Children.Remove(node);
                    }
                }
            }
        }

        void Client_UpdateAppCompleted(object sender, UpdateAppCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
                return;
            }
            if (e.Result.IsSuccess == false)
            {
                this.ShowMessage("操作失败",e.Result.Message);
            }
            else
            {
                // 更改目录结构
                if (SelectedItem.Tags != selectApp.Tags)
                {
                    var item = this.SelectedItem;
                    // 删除原节点。
                    var sourceNode = this.GetDataNode(SelectedItem.Tags);
                    sourceNode.Children.Remove(item);
                    var node = this.GetDataNode(selectApp.Tags);
                    node.Children.Add(item);
                    FillClearTree(this.Datas);
                    this.SelectedItem = item;
                    SelectedItem.Tags = selectApp.Tags;
                }
                SelectedItem.Caption = selectApp.Caption;
                SelectedItem.ImageUrl1 = selectApp.Icon1;
                SelectedItem.Background = selectApp.Bgc;
                SelectedItem.Order = selectApp.Order;
            }
        }

        void Client_DeleteAppsCompleted(object sender, DeleteAppsCompletedEventArgs e)
        {
            DetailIsBusy = false;
            TreeIsBusy = false;
            
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
                return;
            }
            if (e.Result.IsSuccess == false)
            {
                this.ShowMessage("操作失败",e.Result.Message);
            }
            else
            {
                var node = this.GetDataNode(SelectedItem.Tags);
                if (node.Children.Any(p => p.ID == SelectedItem.ID))
                {
                    var curent = node.Children.First(p => p.ID == SelectedItem.ID);
                    node.Children.Remove(curent);
                    if (node.Children.Count == 0)
                    {
                        int index = SelectedItem.Tags.LastIndexOf('\\');
                        string tags = SelectedItem.Tags.Substring(0, index);
                        string caption = SelectedItem.Tags.Substring(index);
                        var parentNode = this.GetDataNode(tags);
                        parentNode.Children.Remove(node);
                    }
                }
            }
        }

        void Client_GetAppsCompleted(object sender, GetAppsCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
            }
            else
            {
                FillTopicTree(e.Result);
                Client.GetServicesAsync();
            }
        }

        void Client_GetServicesCompleted(object sender, GetServicesCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
            }
            else
            {
                FillTopicTree(e.Result);
            }
        }

        void Client_GetParameterCompleted(object sender, GetParameterCompletedEventArgs e)
        {
            DetailIsBusy = false;
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
            }
            else
            {
                this.GotoEditView(e.Result,this.UpdateParameterAction);
            }
        }

        void Client_SearchAppByCodeCompleted(object sender, SearchAppByCodeCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
            }
            else
            {
                this.GotoEditView(selectApp = e.Result, this.UpdateAppAction);
            }
        }

        void Client_SearchServiceByCodeCompleted(object sender, SearchServiceByCodeCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.ShowMessage(e.Error.Message,e.Error.ToString());
            }
            else
            {
                this.GotoEditView(selectService = e.Result, this.UpdateServiceAction);
            }
        }
        #endregion //#region 数据服务操作结果处理函数

        public void SetConfig(Dictionary<string, string> config)
        {
            this.Config = config;

            Client = ServiceLoader.CreateWCFClient<NorOpSvClient>(this.Config["CC_URL"]);

            Client.GetParameterCompleted += Client_GetParameterCompleted;
            Client.UpdateParameterCompleted += Client_UpdateParameterCompleted;

            Client.SearchAppByCodeCompleted += Client_SearchAppByCodeCompleted;
            Client.SearchServiceByCodeCompleted += Client_SearchServiceByCodeCompleted;

            Client.InsertServiceCompleted += Client_InsertServiceCompleted;
            Client.UpdateServiceCompleted += Client_UpdateServiceCompleted;
            Client.DeleteServiceCompleted += Client_DeleteServiceCompleted;
            Client.GetServicesCompleted += Client_GetServicesCompleted;

            Client.InsertAppCompleted += Client_InsertAppCompleted;
            Client.UpdateAppCompleted += Client_UpdateAppCompleted;
            Client.DeleteAppsCompleted += Client_DeleteAppsCompleted;
            Client.GetAppsCompleted += Client_GetAppsCompleted;

            this.Refresh();
        }
        private TopicItemObject GetDataNode(string caption)
        {
            string[] tags = caption.Split('\\');
            TopicItemObject parentNode = null;
            foreach (var tag in tags)
            {
                if (parentNode == null && Datas.Any(p => p.Caption == tag))
                {
                    parentNode = Datas.First(p => p.Caption == tag);
                }
                else if (parentNode != null && parentNode.Children.Any(p => p.Caption == tag))
                {
                    parentNode = parentNode.Children.First(p => p.Caption == tag);
                }
                else
                {
                    var temp = new TopicItemObject()
                    {
                        Caption = tag,
                        ImageUrl1 = "/Resource/0.png",
                        Background="Transparent",
                        Parent = parentNode,
                    };

                    if (parentNode == null)
                    {
                        temp.Tags = tag;
                        Datas.Add(temp);
                    }
                    else
                    {
                        temp.Tags = parentNode.Tags + "\\" + tag;
                        parentNode.Children.Add(temp);
                    }

                    parentNode = temp;
                }
            }
            return parentNode;
        }
        private void FillClearTree(IList<TopicItemObject> items)
        {
            for (int i = 0; i < items.Count; i++)
            {
                var item = items[i];
                if (item.Type == TopicItemType.Directory)
                {
                    if (item.Children.Count == 0)
                    {
                        items.RemoveAt(i);
                        i--;
                        FillClearTree(items);
                    }
                    else
                    {
                        FillClearTree(item.Children);
                    }
                }
                else
                {
                    continue;
                }
            }
        }
        private void FillTopicTree(IList items)
        {
            TopicItemObject treeItem = null;
            foreach (dynamic item in items)
            {
                var parent = GetDataNode(item.Tags);
                treeItem = new TopicItemObject()
                {
                    Caption = item.Caption,
                    ID = item.ID,
                    ImageUrl1 = item.Icon1,
                    Tags = item.Tags,
                    Order = item.Order,
                };
                if (string.IsNullOrEmpty(item.Bgc) == false)
                {
                    treeItem.Background = item.Bgc;
                }

                if (item is ServiceObject)
                    treeItem.Type = TopicItemType.Service;
                else
                    treeItem.Type = TopicItemType.App;
                treeItem.Parent = parent;
                parent.Children.Add(treeItem);
            }
        }

        #region 公共操作指令处理函数定义
        private void OnCollpasedAll()
        {
            foreach (var data in Datas)
            {
                data.IsExpanded = false;
            }
        }
        private void OnExpanedAll()
        {

            foreach (var data in Datas)
            {
                data.IsExpanded = true;
            }
        }
        private void OnDelete(object obj)
        {
            var item = obj as TopicItemObject;
            if (item.Type == TopicItemType.Directory)
            {
                this.ShowMessage("目录节点不允许删除！");
                return;
            }
            bool isService = item.Type == TopicItemType.Service;
            string type = isService ? "服务" : "应用";

            if (MessageBox.Show("确定删除" + type + "[" + item.Caption + "]信息？"
                        , string.Empty
                        , MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                if (Client != null)
                {
                    if (isService)
                    {
                        Client.DeleteServiceAsync(item.ID);
                    }
                    else
                    {
                        Client.DeleteAppsAsync(item.ID);
                    }
                }
                else
                {
                    this.ShowMessage("数据请求服务地址不存在，请检查参数设置或与管理员联系。");
                }
            }
        }
        // 节点选中指令处理函数
        private void OnSelected(object obj)
        {
            if (obj == null) return;
            DetailIsBusy = true;
            SelectedItem = obj as TopicItemObject;
            if (SelectedItem.Type == TopicItemType.Directory)
            {
                this.UpdateParameter(SelectedItem.Caption);
            }
            else if (SelectedItem.Type == TopicItemType.App)
            {
                Client.SearchAppByCodeAsync(SelectedItem.ID);
            }
            else
            {
                Client.SearchServiceByCodeAsync(SelectedItem.ID);
            }

        }
        private void OnSave()
        {
            if (SaveAction != null) SaveAction();
        }
        private void GotoEditView(object toedit, Action result)
        {
            if (toedit is AppObject)
            {
                EditView = new AppPanel()
                {
                    DataContext = toedit
                };
            }
            else if (toedit is ServiceObject)
            {
                EditView = new ServicePanel()
                {
                    DataContext = toedit
                };
            }
            else if (toedit is string)
            {
                var view = new ParameterPanel()
                {
                    Parameter = toedit.ToString(),
                    Caption = SelectedItem.Caption
                };
                EditView = view;
            }
            else
                return;
            DetailIsBusy = false;
            SaveAction = result;
        }

        #region 关于参数
        private void UpdateParameter(string caption)
        {
            DetailIsBusy = true;
            Client.GetParameterAsync(caption);
        }
        private void UpdateParameterAction()
        {
            string key = this.SelectedItem.Caption;
            string value = (editView as ParameterPanel).Parameter;
            Client.UpdateParameterAsync(key, value);
        }
        #endregion //#region 关于参数
        
        #region 关于 Service
        private void InsertService()
        {
            string autoOrderID = string.Empty;
            string tags = string.Empty;
            if (this.SelectedItem == null)
            {
                autoOrderID = "00.00.00";
            }
            else
            {
                TopicItemObject item = null;
                if (this.SelectedItem.Type == TopicItemType.Directory)
                    item = this.SelectedItem;
                else
                    item = this.GetDataNode(this.SelectedItem.Tags);

                string order = item.Children.Max(p => p.Order);
                if (order == null)
                {
                    order = "00.00.00";
                }
                else
                {
                    string first = order.Substring(0, order.Length - 1);
                    string last = order.Substring(order.Length - 1);
                    int value = -1;
                    if (Int32.TryParse(last, out value))
                    {
                        autoOrderID = first + (value + 1).ToString();
                    }
                    else
                    {
                        autoOrderID = first + last + "1";
                    }
                }
                tags = this.SelectedItem.Tags;
            }

            selectService = new ServiceObject()
            {
                Order = autoOrderID,
                ID = Guid.NewGuid().ToString(),
                Tags =tags
            };

            this.GotoEditView(selectService, this.InsertServiceAction);
        }

        private void InsertServiceAction()
        {
            if (Client != null)
                Client.InsertServiceAsync(selectService);
            else
                this.ShowMessage("数据请求服务地址不存在，请检查参数设置或与管理员联系。");
        }
        private void UpdateServiceAction()
        {
            if (Client != null)
                Client.UpdateServiceAsync(selectService);
            else
                this.ShowMessage("数据请求服务地址不存在，请检查参数设置或与管理员联系。");
        }

        #endregion //#region 关于 Service

        #region 关于 App
        private void InsertApp()
        {
            string autoOrderID = string.Empty;
            string tags = string.Empty;
            if (this.SelectedItem == null)
            {
                autoOrderID = "00.00.00";
            }
            else
            {
                TopicItemObject item = null;
                if (this.SelectedItem.Type == TopicItemType.Directory)
                    item = this.SelectedItem;
                else
                    item = this.GetDataNode(this.SelectedItem.Tags);

                string order = item.Children.Max(p => p.Order);
                if (order == null)
                {
                    autoOrderID = "00.00.00";
                }
                else
                {
                    string first = order.Substring(0, order.Length - 1);
                    string last = order.Substring(order.Length - 1);
                    int value = -1;
                    if (Int32.TryParse(last, out value))
                    {
                        autoOrderID = first + (value + 1).ToString();
                    }
                    else
                    {
                        autoOrderID = first + last + "1";
                    }
                }
                tags = this.SelectedItem.Tags;
            }

            selectApp = new AppObject()
            {
                Order = autoOrderID,
                ID = Guid.NewGuid().ToString(),
                Tags = tags
            };

            this.GotoEditView(selectApp, this.InsertAppAction);
        }

        private void InsertAppAction()
        {
            if (Client != null)
                Client.InsertAppAsync(selectApp);
            else
                this.ShowMessage("数据请求服务地址不存在，请检查参数设置或与管理员联系。");
        }
        private void UpdateAppAction()
        {
            if (Client != null)
                Client.UpdateAppAsync(selectApp);
            else
                this.ShowMessage("数据请求服务地址不存在，请检查参数设置或与管理员联系。");
        }
        #endregion //#region 关于 App

        #endregion //#region 公共操作指令处理函数定义

        #region IRefreshAware 成员

        public void Refresh()
        {
            Datas.Clear();
            this.EditView = null;
            Client.GetAppsAsync();
        }

        #endregion
    }
}